package com.cdp.web.controller.system;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cdp.common.core.controller.BaseController;
import com.cdp.common.core.domain.AjaxResult;
import com.cdp.common.core.domain.entity.SysUser;
import com.cdp.common.core.domain.entity.SysWhiteUser;
import com.cdp.common.utils.SecurityUtils;
import com.cdp.framework.web.service.SysRegisterService;
import com.cdp.system.service.ISysConfigService;
import com.cdp.system.service.ISysUserService;
import com.cdp.system.service.SysWhiteUserService;
import com.cdp.system.vo.SysUserV2VO;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 注册验证
 *
 * @author ruoyi
 */
@Slf4j
@Api(value = "用户", tags = {"User Operations"})
@RestController
@RequestMapping()
public class SysRegisterController extends BaseController {

    @Autowired
    private SysWhiteUserService sysWhiteUserService;

    //全球手机号正则表达式
    private static final String PHONE_NUMBER_REGEX = "^(?:\\+?(\\d{1,3}))?[-. (]*(\\d{1,4})?[-. )]*(\\d{1,4})?[-. ]*(\\d{1,4})?[-. ]*(\\d{1,9})?$";
    // 中国内地手机号正则表达式
    private static final String PHONE_NUMBER = "^1[3-9]\\d{9}$";

    @Autowired
    private SysRegisterService registerService;

    @Autowired
    private ISysConfigService configService;
    @Autowired
    private ISysUserService userService;

//    @ApiOperation("用户注册")
//    @PostMapping("/registers")
//    @Transactional
//    public AjaxResult register(@RequestBody SysUser user) {
//        //@Validated 如果 User 对象中有不符合规则的字段，Spring 会自动抛出异常
//        // 手机号码格式验证
//        String phonenumber = user.getPhonenumber();
//        if (!phonenumber.matches(PHONE_NUMBER_REGEX)) {
//            log.error("手机号：{}格式不正确", phonenumber);
//            return AjaxResult.error(400, "手机号码格式不正确");
//        }
//        //用户数据验证
//        if (ObjectUtils.isNotEmpty(user.getPhonenumber())) {
//            //查询之前检查数据的一致性
//            long count = userService.count(new LambdaQueryWrapper<SysUser>()
//                    .eq(SysUser::getPhonenumber, user.getPhonenumber()));
//            if (count > 1) {
//                log.error("在数据库中找到了多条手机号：{}", user.getPhonenumber());
//                return AjaxResult.error(409, "手机号码不唯一，找到了多条记录");//手机号码已经被注册是一个典型的冲突场景
//            }
//
//            SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, user.getPhonenumber()));
//            if (ObjectUtils.isNotEmpty(sysUser)) {
//                log.info("用户：{}手机号码：{}已存在", sysUser, user.getPhonenumber());
//                return AjaxResult.error(409, "用户'" + user.getPhonenumber() + "'注册失败，手机号码已存在");
//            }
//        }
//        user.setNickName(user.getPhonenumber());
//        user.setUserName(user.getPhonenumber());
//        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
//        try {
//            boolean b = userService.insertUser(user);
//            if (b) {
//                log.info("用户：{}注册成功", user.getPhonenumber());
//            } else {
//                log.warn("用户：{}注册失败，未知原因", user.getPhonenumber());
//                return AjaxResult.error(503, "注册失败，请稍后重试");
//            }
//        } catch (Exception e) {
//            log.error("用户：{}注册失败：{}", user.getPhonenumber(), e.getMessage());
//            return AjaxResult.error(503, "注册失败，系统异常");
//        }
//
//
//    }


    @ApiOperation("用户注册")
    @PostMapping("/registers")
    @Transactional
    public AjaxResult register(@RequestBody SysUser user) {
        // 手机号码格式验证
        String phonenumber = user.getPhonenumber();
        if (!phonenumber.matches(PHONE_NUMBER)) {
            log.error("手机号：{} 格式不正确", phonenumber);
            return AjaxResult.error(400, "手机号码格式不正确");
        }

        // 用户数据验证
        if (ObjectUtils.isNotEmpty(phonenumber)) {
            // 检查手机号是否唯一
            long count = userService.count(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber, phonenumber));
            if (count > 1) {
                log.error("在数据库中找到了多条手机号：{}", phonenumber);
                return AjaxResult.error(409, "手机号码不唯一，找到了多条记录");
            }

            // 检查手机号是否已经存在
            SysUser existingUser = userService.getOne(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber, phonenumber), false);
            if (ObjectUtils.isNotEmpty(existingUser)) {
                log.info("用户：{} 手机号码：{} 已存在", existingUser.getUserName(), phonenumber);
                return AjaxResult.error(409, "用户'" + phonenumber + "'注册失败，手机号码已存在");
            }
        }

        // 设置用户默认字段
        user.setNickName(phonenumber);
        user.setUserName(phonenumber);
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        // 尝试插入用户数据
        try {
            boolean isInserted = userService.insertUser(user);
            if (isInserted) {
                log.info("用户：{} 注册成功", phonenumber);
                return AjaxResult.success("注册成功");
            } else {
                log.warn("用户：{} 注册失败，未知原因", phonenumber);
                return AjaxResult.error(503, "注册失败，服务暂时不可用");
            }
        } catch (DataIntegrityViolationException e) {
            log.error("事务回滚：手机号 {} 已存在，违反唯一性约束", phonenumber);
            return AjaxResult.error(422, "注册失败，手机号已存在");
        } catch (Exception e) {
            log.error("事务回滚：{}", e.getMessage());
            return AjaxResult.error(500, "注册失败，系统异常");
        }

    }


    @ApiOperation("用户注册")
    @PostMapping("/registersV2")
    @Transactional
    public AjaxResult registerV2(@RequestBody SysUser user) {



        // 手机号码格式验证
        String phonenumber = user.getPhonenumber();
        if (!phonenumber.matches(PHONE_NUMBER)) {
            log.error("手机号：{} 格式不正确", phonenumber);
            return AjaxResult.error(400, "手机号码格式不正确");
        }


        Integer identify = user.getIdentify();
        if (identify == 0) {
            SysWhiteUser sysWhiteUser = new SysWhiteUser();
            sysWhiteUser.setPhonenumber(phonenumber);
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String formattedDateTime = now.format(formatter);
            sysWhiteUser.setCreateTime(formattedDateTime);
            sysWhiteUserService.save(sysWhiteUser);
        }


        // 用户数据验证
        if (ObjectUtils.isNotEmpty(phonenumber)) {
            // 检查手机号是否唯一
            long count = userService.count(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber, phonenumber));
            if (count > 1) {
                log.error("在数据库中找到了多条手机号：{}", phonenumber);
                return AjaxResult.error(409, "手机号码不唯一，找到了多条记录");
            }

            // 检查手机号是否已经存在
            SysUser existingUser = userService.getOne(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber, phonenumber), false);
            if (ObjectUtils.isNotEmpty(existingUser)) {
                log.info("用户：{} 手机号码：{} 已存在", existingUser.getUserName(), phonenumber);
                return AjaxResult.error(409, "用户'" + phonenumber + "'注册失败，手机号码已存在");
            }
        }

        // 设置用户默认字段
        user.setNickName(phonenumber);
        user.setUserName(phonenumber);
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));


        log.info("插入前 SysUser 对象: {}", JSON.toJSONString(user));

        // 尝试插入用户数据
        try {
            boolean isInserted = userService.insertUser(user);
            if (isInserted) {
                log.info("用户：{} 注册成功", phonenumber);
                return AjaxResult.success("注册成功");
            } else {
                log.warn("用户：{} 注册失败，未知原因", phonenumber);
                return AjaxResult.error(503, "注册失败，服务暂时不可用");
            }
        } catch (DataIntegrityViolationException e) {
            log.error("事务回滚：手机号 {} 已存在，违反唯一性约束", phonenumber);
            return AjaxResult.error(422, "注册失败，手机号已存在");
        } catch (Exception e) {
            log.error("事务回滚：{}", e.getMessage());
            return AjaxResult.error(500, "注册失败，系统异常");
        }

    }


    /**
     * 查询用户
     *
     * @param
     * @param
     * @return
     */


    @GetMapping("/queryUser")
    public AjaxResult queryUser() {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(SysUser::getCreateTime);
        // 1. 查询所有用户
        List<SysUser> sysUsers = userService.list(wrapper);
        // 2. 一次性查询所有白名单手机号
        List<SysWhiteUser> whiteUsers = sysWhiteUserService.list();
        Set<String> whitePhoneSet = new HashSet<>();
        for (SysWhiteUser wUser : whiteUsers) {
            whitePhoneSet.add(wUser.getPhonenumber());
        }
        // 3. 遍历用户列表，判断手机号是否在白名单中，设置property字段
        List<SysUserV2VO> resultList = new ArrayList<>();
        for (SysUser sysUser : sysUsers) {
            SysUserV2VO vo = new SysUserV2VO();
            BeanUtils.copyProperties(sysUser, vo);
            if (whitePhoneSet.contains(sysUser.getPhonenumber())) {
                vo.setProperty("管理员");
            } else {
                vo.setProperty("普通用户");
            }
            resultList.add(vo);
        }
        return AjaxResult.success(resultList);
    }





    @PostMapping("/query/userList")
    public AjaxResult queryUserList(@RequestParam Integer pageNum, @RequestParam Integer pageSize) {
        // 参数校验
        if (pageNum == null || pageSize == null) {
            return AjaxResult.error("分页参数不能为空");
        }

        System.out.println("pageNum: " + pageNum + ", pageSize: " + pageSize);

        try {
            PageHelper.startPage(pageNum, pageSize);
            List<SysUser> sysUsers = userService.list();
            log.info("查询用户列表成功sysUsers={}", sysUsers);
            return AjaxResult.success(sysUsers);
        } catch (Exception e) {
            e.printStackTrace(); // 输出异常栈
            return AjaxResult.error("查询用户列表失败: " + e.getMessage());
        }
    }


}
